//
//  HACTimeLineView.m
//  Pods
//
//  Created by Hotacool on 2017/8/30.
//
//

#import "HACTimeLineView.h"
#import "HACBasicComponents.h"
#import "HACTimeLineEntry.h"
#import "HACBasicInfoEntry.h"

NSString* const HACTimeLineViewDataLabel = @"HACMLineData";

static const NSUInteger HACTimeLineViewLineCount = 2; //分时线和均线
@interface HACTimeLineView ()
/** 分时数据 */
@property (nonatomic, copy) NSArray<HACTimeLineEntry*> *timeLineData;
/** 画线点数据 */
@property (nonatomic, strong) NSMutableArray *lineDrawingData;

@end

@implementation HACTimeLineView

- (void)setUp {
    [super setUp];
    // 初始化页面属性
    self.backgroundColor = [UIColor clearColor];
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    self.xAxisCount = 5;
    self.yAxisCount = 5;
    self.singleWidth = 1;
    self.visualCount = 241;
    self.showAvgLine = YES;
    
    _lineRenderer = [[HACLineRenderer alloc] initWithDataProvider:self];
    self.animator = [[HACAnimator alloc] init];
    self.animator.delegate = self;
}

- (void)setData:(HACChartData *)data {
    if (!data) {
        return;
    }
    //分时数据
    _timeLineData = [data dataSetWithLabel:HACTimeLineViewDataLabel].values;
    HACChartDataSet *tmp = [data dataSetWithLabel:HACBasicDataLabel];
    self.basicInfoData = tmp?(HACBasicInfoEntry*)tmp.values.firstObject:nil;
    
    int showLineCount = 1;
    if (self.showAvgLine) {
        showLineCount += 1;
    }
    //处理数据为 分时线和均线
    _lineDrawingData = [NSMutableArray arrayWithCapacity:showLineCount];
    for (NSInteger index = 0; index < showLineCount; index++) {
        HACLineComponents *lineItem = [[HACLineComponents alloc] init];
        lineItem.isCurve = NO;
        if (index == 0) {
            lineItem.lineColor = RGB_HEX(0x3C9FFC);
            lineItem.fillColor = [UIColor colorWithRed:241/255.0f green:248/255.f blue:254/255.f alpha:0.5];
        } else {
            lineItem.lineColor = [UIColor orangeColor];
        }
        lineItem.index = index;
        [_lineDrawingData addObject:lineItem];
    }
    self.startIndex = 0;
    self.endIndex = MAX(0, (NSInteger)_timeLineData.count - 1);
    
    [super setData:data];
}

- (void)addIncrementData:(HACChartData *)data {
    [super addIncrementData:data];
    NSArray *appendData = [data dataSetWithLabel:HACTimeLineViewDataLabel].values;
    if (appendData&&appendData.count>0) {
        _timeLineData = [_timeLineData arrayByAddingObjectsFromArray:appendData];
        self.startIndex = 0;
        self.endIndex = MAX(0, (NSInteger)_timeLineData.count - 1);
        //calculate max&min
        CGFloat max, min;
        for (HACTimeLineEntry *item in appendData) {
            if ([item isKindOfClass:[HACTimeLineEntry class]]) {
                max = [self maxValueForData:item];
                min = [self minValueForData:item];
                if (max != kDrawingInvaildValue && max > self.maxValue) {
                    self.maxValue = max;
                }
                if (min != kDrawingInvaildValue && min < self.minValue) {
                    self.minValue = min;
                }
            }
        }
    }
}

- (void)clean {
    _timeLineData = nil;
    _lineDrawingData = nil;
    self.startIndex = 0;
    self.endIndex = 0;
    [super clean];
}

- (NSInteger)actualCount {
    return _timeLineData?_timeLineData.count:0;
}

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    CGContextRef context = UIGraphicsGetCurrentContext();
    [self.lineRenderer drawInRect:rect context:context];
}

#pragma mark - HACAnimatorDelegate
- (void)animatorUpdated:(HACAnimator *)animator {
    [self setNeedsDisplay];
}

- (void)animatorStopped:(HACAnimator *)animator {
    [self setNeedsDisplay];
}

#pragma mark - provider protocol
- (NSArray *)lineDatasInRect:(CGRect)rect {
    if (!self.data || [self lineValueForItem:nil lineIndex:0] == kDrawingInvaildValue) // 返回无效数据不做默认处理
        return nil;
    
    for (HACLineComponents *lineItem in self.lineDrawingData) {
        lineItem.pointCount = (self.endIndex - self.startIndex) + 1;
        NSMutableArray *pointsArray = [NSMutableArray array];
        
        long len = self.endIndex - self.startIndex + 1;
        int phaseEnd = MIN(self.actualCount, len)*self.animator.phaseX;//动画
        for (NSInteger i = self.startIndex; i <= self.endIndex && i < self.actualCount; i++) {
            if (i >= phaseEnd) {
                break;
            }
            id pointData = self.timeLineData[i];
            CGFloat x = 0.0, y = 0.0;
            x = [self xPointForIndex:i inRect:self.pointRect];
            if (self.singleWidth > 0) {
                // 如果已经绘制rect，需要偏移1/2 singleWidth实现居中
                x += self.singleWidth / 2;
            }
            CGFloat value = [self lineValueForItem:pointData lineIndex:lineItem.index];
            y = [self calculatorYForValue:value min:self.minValue max:self.maxValue inRect:self.pointRect];
            [pointsArray addObject:NSStringFromCGPoint(CGPointMake(x, y))];
        }
        lineItem.pointArray = pointsArray;
    }
    return self.lineDrawingData;
}

- (CGFloat)lineValueForItem:(HACTimeLineEntry *)data lineIndex:(NSInteger)index {
    if (index == 0) {
        return data.newprice;
    } else {
        return data.avgPrice;
    }
}

// 计算最大，最小值
- (void)calculateLimitValue {
    CGFloat max = FLT_MIN;
    CGFloat min = FLT_MAX;
    CGFloat value;
    
    for (NSInteger i = self.startIndex; i <= self.endIndex && i < self.actualCount; i++) {
        id model = self.timeLineData[i];
        
        value = [self maxValueForData:model];
        if (value != kDrawingInvaildValue && value > max) {
            max = value;
        }
        
        value = [self minValueForData:model];
        if (value != kDrawingInvaildValue && value < min) {
            min = value;
        }
    }
    self.maxValue = (max == FLT_MIN) ? .0 : max;
    self.minValue = (min == FLT_MAX) ? .0 : min;
    //调整位置
    if (self.basicInfoData&&self.maxValue!=0&&self.minValue!=0) {
        float base = self.basicInfoData.previousPrice;
        float a = ABS(self.maxValue - base);
        float b = ABS(base - self.minValue);
        if (base > self.maxValue) {
            self.maxValue = base + b;
        } else if (base < self.minValue) {
            self.minValue = base - a;
        } else {
            if (a > b) {
                self.minValue = base - a;
            } else {
                self.maxValue = base + b;
            }
        }
    }
    
    // axis custom setting
    if (self.leftAxis.customAxisMin) {
        self.minValue = self.leftAxis.axisMinimum;
    }
    CGFloat w = ABS(self.maxValue - self.minValue);
    if (self.leftAxis.spaceTop > 0) {
        self.maxValue += self.leftAxis.spaceTop*w;
    }
    if (self.leftAxis.spaceBottom > 0 && !self.leftAxis.customAxisMin) {
        self.minValue -= w*self.leftAxis.spaceBottom;
    }
}

- (CGFloat)maxValueForData:(HACTimeLineEntry *)data {
    if (self.showAvgLine) {
        return MAX(data.newprice, data.avgPrice);
    } else {
        return data.newprice;
    }
}

- (CGFloat)minValueForData:(HACTimeLineEntry *)data {
    if (self.showAvgLine) {
        return MIN(data.newprice, data.avgPrice);
    } else {
        return data.newprice;
    }
}

#pragma mark -- api
- (NSUInteger)indexAtChartForCoordinate:(CGPoint)point {
    NSInteger focusIndex = [super indexAtChartForCoordinate:point];
    
    CGFloat offsetX = point.x - CGRectGetMinX(self.pointRect);
    focusIndex = offsetX / self.singleWidth;
    focusIndex = MAX(MIN(focusIndex, self.endIndex), self.startIndex);
    return focusIndex;
}

- (CGPoint)pointAtChartForIndex:(NSUInteger)index {
    CGPoint point = [super pointAtChartForIndex:index];
    HACLineComponents *lineItem = self.lineDrawingData.firstObject;
    if (lineItem.pointArray && lineItem.pointArray.count > index) {
        point = CGPointFromString(lineItem.pointArray[index]);
    }
    return point;
}

- (HACChartDataEntry*)dataAtChartForCoordinate:(CGPoint)point {
    HACChartDataEntry *indexData = [super dataAtChartForCoordinate:point];
    NSUInteger focusIndex = [self indexAtChartForCoordinate:point];
    if (self.timeLineData && focusIndex < self.timeLineData.count) {
        indexData = self.timeLineData[focusIndex];
    }
    return indexData;
}

- (HACChartDataEntry*)dataAtChartForIndex:(NSUInteger)focusIndex {
    HACChartDataEntry *indexData = [super dataAtChartForIndex:focusIndex];
    if (self.timeLineData && focusIndex < self.timeLineData.count) {
        indexData = self.timeLineData[focusIndex];
    }
    return indexData;
}
@end
